package softwaretest.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import softwaretest.Domain.SensorToken;
import softwaretest.repository.SensorTokenRepository;

import java.util.Map;

@Service
public class TokenService {

    @Autowired
    private SensorTokenRepository sensorTokenRepository;

    private static final String TOKEN_URL = "https://fbox360.com/idserver/core/connect/token";

    public SensorToken fetchSensorAccessToken() {
        RestTemplate restTemplate = new RestTemplate();

        // Construct the request headers
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);

        // Construct the request parameters
        MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
        requestParams.add("scope", "fbox");
        requestParams.add("client_id", "68db2e8bda8d47b5b5db7eaf71c7dcdd");
        requestParams.add("client_secret", "76dc724c95004acab25482d344dab407");
        requestParams.add("grant_type", "client_credentials");

        // Create the request entity
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestParams, headers);

        try {
            // Get the token
            ResponseEntity<Map> responseEntity = restTemplate.exchange(TOKEN_URL, HttpMethod.POST, requestEntity, Map.class);
            Map<String, Object> response = responseEntity.getBody();
            if (response != null && response.containsKey("access_token")) {
                SensorToken newToken = new SensorToken();
                newToken.setAccessToken((String) response.get("access_token"));
                newToken.setExpiresIn(((Number) response.get("expires_in")).longValue());
                newToken.setTokenType((String) response.get("token_type"));
                newToken.setScope((String) response.get("scope"));
                newToken.setExpirationTime(System.currentTimeMillis() + (newToken.getExpiresIn() * 1000)); // Set expiration time

                sensorTokenRepository.save(newToken); // Save to the database
                return newToken;
            }
        } catch (Exception e) {
            // Handle exceptions
            System.err.println("Error fetching token: " + e.getMessage());
        }
        return null;
    }

    public SensorToken getLatestSensorToken() {
        return sensorTokenRepository.findTopByOrderByExpirationTimeDesc().orElse(null);
    }

    public SensorToken getValidSensorToken() {
        SensorToken token = getLatestSensorToken(); // Get the latest token
        long currentTime = System.currentTimeMillis();

        // Check if the token is null or expired
        if (token == null || currentTime >= token.getExpirationTime()) {
            return fetchSensorAccessToken(); // Fetch a new token if expired or null
        }
        return token; // Return the valid token
    }
}